﻿using System;
using System.Collections.Generic;
using System.Linq;
using EzDesk.Core.Interface;
using EzDesk.Core.Model;
using EzDesk.Utility.Log;

namespace EzDesk.Core.ServiceImpl.Services
{
    public partial class CoreService : ICoreService
    {
        private const string CORE_PERMISSION_NAME = "CORE";
        
        public void RegisterPermission(Permission permission)
        {
            if (permission == null)
            {
                throw new Exception("权限不存在");
            }
            var query = _permissionRepository
                .GetAll()
                .Where(p => p.AppName == permission.AppName && p.Name == permission.Name);
            if (query.Count() > 0)
            {
                throw new Exception("该权限已存在");
            }

            _permissionRepository.Add(permission, true);
        }

        public IList<Permission> GetPermissions(string appName)
        {
            App app = null;
            if (!string.IsNullOrEmpty(appName))
            {
                app = _appRepository.GetAppByName(appName);
                if (app == null)
                {
                    throw new Exception("找不到AppId");
                }
            }           

            return _permissionRepository
                .GetAll()
                .Where(p => p.AppName == appName)
                .ToList();
        }

        public Permission GetPermission(string permissionStr)
        {
            return getPermissionByPermissionStr(permissionStr);
        }

        public bool UserHasPermission(string permissionStr, Guid userId)
        {
            bool hasPermission = false;
            var groups = GetUserInGroups(userId);
            foreach (var group in groups)
            {
                hasPermission = GroupHasPermission(permissionStr, group.Id);
                if (hasPermission)
                {
                    break;
                }
            }
            return hasPermission;
        }

        public bool GroupHasPermission(string permissionStr, Guid groupId)
        {
            Permission permission = getPermissionByPermissionStr(permissionStr);
            Guid permissionId = permission.Id;
            return _permissionRepository.GroupHasPermission(permissionId, groupId);
        }

        public void SetGroupPermission(string permissionStr, Guid groupId, bool hasPermission)
        {
            Permission permission = getPermissionByPermissionStr(permissionStr);
            Guid permissionId = permission.Id;
            _permissionRepository.SetGroupPermission(permissionId, groupId, hasPermission);
        }


        #region [ private methods ]

        private Permission getPermissionByPermissionStr(string permissionStr)
        {
            string appName = permissionStr.Split('_').First();
            if (string.IsNullOrEmpty(appName))
            {
                LogEx.EXCEPT("Core - Permission", "Permission名称格式错误！  PermissionStr: " + permissionStr);
                throw new ArgumentException("permissionStr错误");
            }

            string permissionName = permissionStr.Substring(appName.Length + 1);

            Guid? appId = null;
            if (appName != CORE_PERMISSION_NAME)
            {
                bool isAppExisted = _appRepository.IsAppExisted(appName);
                if (!isAppExisted)
                {
                    throw new Exception("App名称错误");
                }
            }

            try
            {
                var permission = _permissionRepository
                    .GetAll()
                    .Where(p => p.AppName == appName && p.Name == permissionName)
                    .Single();
                return permission;

            }catch(Exception ex)
            {
                LogEx.ERROR("Core - Permission", "传入了非法的PermissionStr: " + permissionStr, ex);
                throw new ArgumentException("permissionStr错误", ex);
            }

            
        }

        #endregion
    }
}
